package site.shihuan.helpdesk.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import site.shihuan.helpdesk.security.context.UserContextHolder;
import site.shihuan.helpdesk.security.context.UserContext;
import site.shihuan.helpdesk.common.model.Constants;
import site.shihuan.helpdesk.security.annotation.Secured;
import site.shihuan.helpdesk.security.exception.AccessException;
import site.shihuan.helpdesk.security.manager.AuthManager;
import site.shihuan.helpdesk.common.model.JwtUser;
import site.shihuan.helpdesk.common.model.Permission;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器，身份验证和权限验证
 *
 * @author 周世焕
 * @Date 2021/1/23 13:22
 */
@Component
@Slf4j
public class WebInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private AuthManager authManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String clientId = request.getHeader(Constants.HEADER_CLIENT_ID);
        UserContextHolder userContextHolder = new UserContextHolder();
        userContextHolder.setClientId(clientId);
        Secured secured = null;
        JwtUser jwtUser = null;
        try {
            //身份验证
            jwtUser = authManager.authenticate(request);
            userContextHolder.setUser(jwtUser);
        }catch (AccessException e){

        }
        UserContext.setContext(userContextHolder);
        if (handler instanceof HandlerMethod
                && (secured = ((HandlerMethod) handler).getMethodAnnotation(Secured.class)) != null) {
            //权限认证，会抛错误
            try {
                authManager.authorize(new Permission(secured.resource(),secured.action().toString()),jwtUser);
            }catch (AccessException e){
                log.debug("权限错误: ",e);
                return false;
            }
        }
        return true;
    }
}
